#include "lcd.h"

int *plcd = NULL;
int fb_fd = -1;        // 帧缓冲设备文件描述符
int screen_size = 0;   // 屏幕缓冲区大小
// 初始化帧缓冲设备
int init_framebuffer()
{
    // 打开帧缓冲设备
    fb_fd = open("/dev/fb0", O_RDWR);
    if (fb_fd == -1)
    {
        perror("open framebuffer failed");
        return -1;
    }
    
    // 获取屏幕信息（简化版，实际应使用ioctl获取）
    screen_size = 800 * 480 * 4;  // 800x480分辨率，32位色
    
    // 内存映射帧缓冲设备
    plcd = mmap(NULL, screen_size, PROT_READ | PROT_WRITE, MAP_SHARED, fb_fd, 0);
    if (plcd == MAP_FAILED)
    {
        perror("mmap failed");
        close(fb_fd);
        return -1;
    }
    
    return 0;
}

// 释放帧缓冲设备资源
void cleanup_framebuffer()
{
    if (plcd != MAP_FAILED && plcd != NULL)
    {
        munmap(plcd, screen_size);
        plcd = NULL;
    }
    
    if (fb_fd != -1)
    {
        close(fb_fd);
        fb_fd = -1;
    }
}
//LCD初始化函数
int LCD_Init(void)
{
    // 1.打开文件		//"/dev/fb0"
    int fd = open("/dev/fb0",O_RDWR);
    if(fd == -1)
    {
        perror("open error\n");
        return -1;
    }
    plcd = (int *)mmap(NULL,800*480*4,
                            PROT_READ | PROT_WRITE,
                            MAP_SHARED,
                            fd,
                            0);
    if(plcd == MAP_FAILED)
    {
        perror("mmap error\n");
        return -1;
    }

    return fd;
}

//显示屏关闭以及解除映射
void close_fd(int fd)
{
    munmap(plcd,800*480*4); //解除映射
    close(fd);
}

/*
    display_point:显示有一个点
    @x：点的横坐标
    @y：点的纵坐标
    @color：要显示的颜色
*/
void display_point(int x,int y,int color)
{
    //为了防止有呆逼，憨批，坐标的范围都不清楚的人
    if(x >= 0 && x < 800 && y >= 0 && y < 480)
    {
        *(plcd + 800*y + x) = color;
    }
}
/*
    display_sqare:显示一个矩形
    @x:起始横坐标
    @y:起始的纵坐标
    @len：宽
    @h:高
    @color：要显示的颜色
*/
void display_sqare(int x, int y,int len,int h,int color)
{
    for(int i=0;i<len;i++)
        for (int j = 0;j < h;j++)
        {
            display_point(i+x, j+y, color);
        }
}

/*
    display_cycle: 显示一个圆
    @x: 圆心的横坐标
    @y: 圆心的纵坐标
    @r: 半径
    @color：要显示的颜色
*/
void display_cycle(int x, int y, int r, int color)
{
    int x0 = 0;
    int y0 = r;
    int d = 1 - r;
    int deltaE = 3;
    int deltaSE = -2 * r + 5;
    
    // 绘制初始水平直径
    for (int i = x - r; i <= x + r; i++) {
        display_point(i, y, color);
    }
    
    // 绘制8个对称点并填充水平线
    while (x0 <= y0) {
        //填充水平线段
        for (int i = x - x0; i <= x + x0; i++) {
            display_point(i, y + y0, color);
            display_point(i, y - y0, color);
        }
        for (int i = x - y0; i <= x + y0; i++) {
            display_point(i, y + x0, color);
            display_point(i, y - x0, color);
        }
        
        if (d < 0) 
        {
            d += deltaE;
            deltaE += 2;
            deltaSE += 2;
        } 
        else {
            d += deltaSE;
            deltaE += 2;
            deltaSE += 4;
            y0--;
        }
        x0++;
    }
}